<template>
  <tool-bar nav=""
            style="background-color: #d6e5ff;padding:4px;border-radius:4px;">
    <el-button @click="addRoot()">添加</el-button>
    <template #append>
      <div style="display: flex">
        <kv label="产品线">
          <product-line v-model="$data.query.productLineCode" @change="pl_change"></product-line>
        </kv>
        <kv label="应用">
          <selector url="/dev/data-model/apps" clearable v-model="$data.query.app"
                    @change="app_change"></selector>
        </kv>
      </div>
      <div style="margin-left:10px;" v-if="$data.current && $data.current.wbs">
        <template v-for="(item,index) in $data.current.wbs" :key="item.id">
          <label v-if="index != 0">&gt;</label>
          <label style="margin: 4px;">{{ item.name }}</label>
        </template>
      </div>
    </template>
  </tool-bar>

  <div id="m2" ref="m2">
    <div @click="edit_click">
      <el-icon>
        <EditPen/>
      </el-icon>
      修改
    </div>
    <div @click="append_click">
      <el-icon>
        <CirclePlus/>
      </el-icon>
      添加
    </div>
    <div @click="remove_click">
      <el-icon>
        <Remove/>
      </el-icon>
      删除
    </div>
  </div>

  <div style="display: flex;flex:1;">
    <el-tree
        style="width:200px;background-color: #fffdf6;border-radius: 4px;"
        :data="$data.list"
        check-on-click-node
        highlight-current
        draggable
        node-key="id"
        ref="tree"
        :props="{label:'name',children:'logicChildren'}"
        default-expand-all
        :expand-on-click-node="false"

        @current-change="current_change"

        :allow-drop="allowDrop"
        :allow-drag="allowDrag"
        @node-drag-start="handleDragStart"
        @node-drag-enter="handleDragEnter"
        @node-drag-leave="handleDragLeave"
        @node-drag-over="handleDragOver"
        @node-drag-end="handleDragEnd"
        @node-drop="handleDrop"
    >
      <template #default="{ node, data }">
        <div class="line" v-menu:m2 @context="menu_context(node,data)">
          <span>{{ data.name }}</span>
          <label>{{ data.logicChildren.length }}</label>
        </div>
      </template>
    </el-tree>

    <slot></slot>
  </div>
</template>
<script setup>
import productLine from "@/component/product-line.vue";
import {CirclePlus, Plus, Remove, EditPen} from '@element-plus/icons-vue'




defineOptions({
  name: "tree-type",
  inheritAttrs: true,
});


//定义事件
let $emit = defineEmits(["update:modelValue", "change", "reload"]);

//定义属性
var $props = defineProps({list: {type: Array}});


//定义data
let $data = reactive({
  //默认查询条件,默认存储
  list: [],
  context: {},
  query: {},
  current: null
})

const tree = ref();

const pl_change = (v) => {
  jv.$saveData("query", $data.query);

  loadData()
}

const app_change = (v) => {
  jv.$saveData("query", $data.query);

  console.log("app_change: " + v)
  loadData()
}


const getWbs = (id, list) => {
  if (!list.length) {
    return [];
  }

  for (var it of list) {
    if (it.id == id) {
      return [it];
    }
    if (it.logicChildren.length) {
      var sub = getWbs(id, it.logicChildren);

      if (sub) {
        return [it, ...sub];
      }
    }
  }
}


const menu_context = (node, data) => {
  $data.context.node = node;
  $data.context.data = data;
}

const handleDragStart = (node, ev) => {
  console.log('drag start', node)
}

const handleDragEnter = (draggingNode, dropNode, ev) => {
  console.log('tree drag enter:', dropNode.label)
}

const handleDragLeave = (draggingNode, dropNode, ev) => {
  console.log('tree drag leave:', dropNode.label)
}

const handleDragOver = (draggingNode, dropNode, ev) => {
  console.log('tree drag over:', dropNode.label)
}

const handleDragEnd = (draggingNode, dropNode, dropType, ev) => {
  console.log('tree drag end:', dropNode && dropNode.label, dropType)
}

const handleDrop = (draggingNode, dropNode, dropType, ev) => {
  var id = draggingNode.data.id;
  var target = dropNode.data;
  var pid = "";

  if (dropType == "before" || dropType == "after") {
    pid = target.logicParent.id;
  } else if (dropType == "inner") {
    pid = target.id;
  }

  jv.$http.post("/dev/data-model/set-pid", {id: id, pid: pid}).then(res => {

  });
  console.log('tree drop:', dropNode.label, dropType)
}

const allowDrop = (draggingNode, dropNode, type) => {
  return true;
}
const allowDrag = (draggingNode) => {
  return true;
}


const current_change = (data) => {
  data = data || {};
  data.wbs = getWbs(data.id, $data.list);
  if (data.id) {
    $data.current = data;
    $emit("update:modelValue", data);
  }
}

const append_click = () => {
  const data = $data.context.data;
  jv.prompt("添加节点，父节点：" + data.name).then(res => {
    jv.$http.post("/dev/data-model-tree/save", {
      name: res.value,
      parent: {id: data.id, name: data.name}
    }).then(res => {
      loadData();
    })
  })
}

const add_click = () => {
  jv.prompt("添加根节点名称：").then(res => {
    jv.$http.post("/dev/data-model-tree/save", {name: res.value}).then(res => {
      loadData();
    })
  })
}

const edit_click = () => {
  //记录上次点击行
  const data = $data.context.data;
  jv.prompt("修改节点，当前名称: " + data.name).then(res => {

    data.name = res.value;

    jv.$http.post("/dev/data-model-tree/save", data).then(res => {
      loadData();
    })
  })
}


const remove_click = () => {
  const data = $data.context.data;
  var rowName = data.name;
  jv.confirm('确认删除 ' + rowName + ' 吗？').then(res => {
    jv.$http.post("/dev/data-model/delete/" + data.id).then(res => {
      loadData();
    })
  })
}

const proc_version = (list) => {
  list.forEach(item => {
    item.version = 0;
    proc_version(item.logicChildren)
  })
}


let urlTypeIdSetted = false;
const init_value = () => {
  if (urlTypeIdSetted) {
    return;
  }
  urlTypeIdSetted = true;
  var typeId = jv.$route.query.typeId;
  if ($data.current  && typeId != $data.current.id) {
    var item = findItemFromTree(typeId);
    if (item) {
      current_change(item);
    }
  }
}

const loadData = () => {
  return jv.$http.post("/dev/data-model-tree/list", $data.query).then(res => {
    $data.list = res.data;

    proc_version($data.list);

    nextTick(init_value)
  })
}

const root_click = () => {
  $data.current = {productLine: {}};
}

const findItemFromTree = (id, list) => {
  list = list || $data.list;
  for (let i = 0, len = list.length; i < len; i++) {
    var item = list[i];
    if (item.id == id) {
      return item;
    }

    if (!item.logicChildren) {
      continue
    }

    item = findItemFromTree(id, item.logicChildren);
    if (item) {
      return item;
    }
  }
}


onMounted(function () {
  jv.$loadData("query", v => $data.query = v);

  loadData().then(v => {
    var id = jv.$route.query.id;
    if (id) {
      $data.current = findItemFromTree(id);
    } else {
      $data.current = {productLine: {}};
    }
  })
})


const countChange = list => {
  if (!$data.list.length) {
    return;
  }

  list.forEach(item => {
    var dbOne = findItemFromTree(item.id);
    if (!dbOne) {
      return;
    }

    dbOne.models = item.models;
  })
}


defineExpose({
  countChange: countChange,
  addRoot: add_click
})
</script>

<style scoped lang="scss">

.line {
  flex: 1;
  display: flex;
  justify-content: space-between;
}

</style>